#pragma once
#include <string>
#include <unordered_map>
namespace Token
{
    using TokenType = std::string;
    
    const TokenType ILLEGAL = "ILLEGAL";
    const TokenType MEOF = "EOF";
    
    // 标记符+字面量
    const TokenType IDENT = "IDENT"; // main,...
    const TokenType CINT = "CINT"; // constant int

    // 运算符
    const TokenType ASSIGN = "=";
    const TokenType PLUS = "+";
    const TokenType MINUS = "-";
    const TokenType BANG = "!";
    const TokenType ASTERISK = "*";
    const TokenType SLASH = "/";

    const TokenType EQ = "==";
    const TokenType NOT_EQ = "!=";

    const TokenType LT = "<";
    const TokenType GT = ">";
    const TokenType COLON = ":";
    
    // 分隔符
    const TokenType SEMICOLON = ";";
    const TokenType COMMA = ",";
    
    const TokenType LPAREN = "(";
    const TokenType RPAREN = ")";
    const TokenType LBRACE = "{";
    const TokenType RBRACE = "}";

    const TokenType LBRACKET = "[";
    const TokenType RBRACKET = "]";

    // 关键字
    const TokenType KINT = "KINT"; // keyword int
    const TokenType VOID = "VOID";
    const TokenType RETURN = "RETURN"; 

    struct Token
    {
        Token(TokenType type, std::string literal) : m_type(type), m_literal(literal) {}
        TokenType m_type;
        std::string m_literal;
    };
    
    static std::unordered_map<std::string, TokenType> keywords
    {
        {"int" , KINT},
        {"void", VOID},
        {"return", RETURN}
    };

    static TokenType LookUpIdent(std::string ident)
    {
        if (keywords.find(ident) != keywords.end())
        {
            return keywords[ident];
        }
        return IDENT;
    }
}